package com.larly.service.impl;

import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.conditions.query.QueryWrapper;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.larly.common.PageRequest;
import com.larly.exception.BusinessException;
import com.larly.exception.ErrorCode;
import com.larly.exception.ThrowUtils;
import com.larly.model.domain.PrivateMessage;
import com.larly.model.domain.User;
import com.larly.model.dto.privatemessage.PrivateMessageCreateRequest;
import com.larly.model.vo.PrivateMessageVO;
import com.larly.service.NotificationService;
import com.larly.service.PrivateMessageService;
import com.larly.mapper.PrivateMessageMapper;
import com.larly.service.UserService;
import io.swagger.models.auth.In;
import lombok.extern.slf4j.Slf4j;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import javax.annotation.Resource;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

/**
 * @author 许颢达
 * @description 针对表【private_message(私信表)】的数据库操作Service实现
 * @createDate 2025-09-02 12:31:02
 */
@Service
@Slf4j
public class PrivateMessageServiceImpl extends ServiceImpl<PrivateMessageMapper, PrivateMessage>
        implements PrivateMessageService {

    public static final Long THREE_DAYS = 3 * 24 * 60 * 60 * 1000L;

    @Resource
    private UserService userService;

    @Resource
    private NotificationService notificationService;

    /**
     * 创建私信
     *
     * @param privateMessageCreateRequest
     * @return
     */
    @Override
    @Transactional(rollbackFor = Exception.class)
    public boolean createPrivateMessage(PrivateMessageCreateRequest privateMessageCreateRequest, Integer userId) {
        // 1、校验：接受者的id不能是自己
        Integer receiverId = privateMessageCreateRequest.getReceiverId();
        if (receiverId.equals(userId)) {
            throw new BusinessException(ErrorCode.PARAM_ERROR, "接受者ID不能是自己");
        }
        // 2、将之前的消息设置为旧消息（便于后查找旧聊天记录）
        lambdaUpdate().eq(PrivateMessage::getReceiverId, receiverId)
                .eq(PrivateMessage::getSenderId, userId)
                .or()
                .eq(PrivateMessage::getReceiverId, userId)
                .eq(PrivateMessage::getSenderId, receiverId)
                .set(PrivateMessage::getIsLatest, 0)
                .update();
//        ThrowUtils.throwIf(!update, ErrorCode.OPERATION_DENIED, "更新旧消息失败");

        // 3、创建消息
        PrivateMessage privateMessage = new PrivateMessage();
        privateMessage.setSenderId(userId);
        privateMessage.setReceiverId(receiverId);
        privateMessage.setContent(privateMessageCreateRequest.getContent());
        privateMessage.setMsgType(privateMessageCreateRequest.getMsgType());
        privateMessage.setIsRead(0);// 未读
        Date date = new Date();
        privateMessage.setSendTime(date);
        privateMessage.setExpireTime(new Date(System.currentTimeMillis() + THREE_DAYS));
        privateMessage.setIsLatest(1);// 最新

        boolean save = save(privateMessage);
        ThrowUtils.throwIf(!save, ErrorCode.SYSTEM_ERROR, "创建私信失败");

        // 通知用户私信
        notificationService.triggerFollowNotify(userId, receiverId);
        log.info("创建私信成功：{}", privateMessage);
        return true;
    }

    /**
     * 查询历史
     *
     * @param pageRequest 分页参数
     * @param senderId 发送者ID
     * @param receiverId 接受者ID
     * @return 私信列表
     */
    @Override
    public List<PrivateMessageVO> queryHistory(PageRequest pageRequest, Integer senderId, Integer receiverId) {
        QueryWrapper<PrivateMessage> queryWrapper = new QueryWrapper<>();
        queryWrapper.eq("sender_id", senderId)
                .eq("receiver_id", receiverId)
                .eq("is_latest", 0)
                .or()
                .eq("sender_id", receiverId)
                .eq("receiver_id", senderId)
                .eq("is_latest", 0)
                .orderByDesc("send_time");
        Page<PrivateMessage> page = new Page<>(pageRequest.getPageNum(), pageRequest.getPageSize());
        // 分页查询
        Page<PrivateMessage> messagePage = this.page(page, queryWrapper);

        // 转换为VO（补充发送者信息）
        return messagePage.convert(message -> {
            User sender = userService.getById(message.getSenderId());
            String nickname = sender != null ? sender.getNickname() : "匿名用户";
            String avatar = sender != null ? sender.getAvatar() : "";
            return PrivateMessageVO.fromEntity(message, nickname, avatar);
        }).getRecords();
    }

    /**
     * 读取私信
     *
     * @param senderId 发送者ID
     * @param receiverId 接受者ID
     * @return 是否成功
     */
    @Override
    public boolean readPrivateMessage(Integer senderId, Integer receiverId) {
        boolean update = lambdaUpdate().eq(PrivateMessage::getSenderId, senderId)
                .eq(PrivateMessage::getReceiverId, receiverId)
                .set(PrivateMessage::getIsRead, 1)
                .or()
                .eq(PrivateMessage::getSenderId, receiverId)
                .eq(PrivateMessage::getReceiverId, senderId)
                .set(PrivateMessage::getIsRead, 1)
                .update();

        ThrowUtils.throwIf(!update, ErrorCode.OPERATION_DENIED, "更新私信失败");
        return true;
    }

    /**
     * 查询最新列表
     *
     * @param currentUserId 当前用户ID
     * @return 最新列表
     */
    @Override
    public List<PrivateMessageVO> queryLatestList(Integer currentUserId) {
        List<PrivateMessage> messageList = lambdaQuery().eq(PrivateMessage::getReceiverId, currentUserId)
                .eq(PrivateMessage::getIsLatest, 1)
                .or()
                .eq(PrivateMessage::getSenderId, currentUserId)
                .eq(PrivateMessage::getIsLatest, 1)
                .orderByDesc(PrivateMessage::getSendTime)
                .list();

        // 转换为VO并补充对方用户信息
        return messageList.stream().map(message -> {
            // 确定对方用户ID
            Integer targetUserId = message.getSenderId() == currentUserId
                    ? message.getReceiverId()
                    : message.getSenderId();

            User targetUser = userService.getById(targetUserId);
            String targetNickname = targetUser != null ? targetUser.getNickname() : "匿名用户";
            String targetAvatar = targetUser != null ? targetUser.getAvatar() : "";

            // 统计未读消息数量
            long unreadCount = countUnreadByTarget(currentUserId, targetUserId);

            PrivateMessageVO vo = PrivateMessageVO.fromEntity(message, targetNickname, targetAvatar);
            vo.setReceiverId(targetUserId.intValue()); // 重置接收者为对方ID
            vo.setIsRead(unreadCount > 0 ? 0 : 1); // 会话是否有未读
            return vo;
        }).collect(Collectors.toList());
    }

    /**
     * 统计用户与目标用户的未读消息数量
     */
    @Override
    public Long countUnreadByTarget(Integer currentUserId, Integer targetUserId) {
        LambdaQueryWrapper<PrivateMessage> queryWrapper = new LambdaQueryWrapper<>();
        queryWrapper.eq(PrivateMessage::getReceiverId, currentUserId.intValue())
                .eq(PrivateMessage::getSenderId, targetUserId.intValue())
                .eq(PrivateMessage::getIsRead, 0);

        return count(queryWrapper);
    }
}




